package com.jinxin.platform.cdsideparkmgr.controller;

import com.alibaba.fastjson.JSONObject;
import com.jinxin.platform.base.api.annotation.APCOSApi;
import com.jinxin.platform.base.api.annotation.APCOSApiOperation;
import com.jinxin.platform.base.api.constant.APCOSApiConstans;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.cdsideparkmgr.bean.*;
import com.jinxin.platform.cdsideparkmgr.common.Constant;
import com.jinxin.platform.cdsideparkmgr.common.SysOrgInfo;
import com.jinxin.platform.cdsideparkmgr.common.SysUserVO;
import com.jinxin.platform.cdsideparkmgr.mapper.CdsideparkmgrNoticeMapper;
import com.jinxin.platform.cdsideparkmgr.mapper.CdsideparkmgrProjectCarMapper;
import com.jinxin.platform.cdsideparkmgr.mapper.CdsideparmgrkUserMapper;
import com.jinxin.platform.cdsideparkmgr.rpc.CdsideparkmgrRpc;
import com.jinxin.platform.cdsideparkmgr.service.*;
import com.jinxin.platform.cdsideparkmgr.utils.DateUtil;
import com.jinxin.platform.cdsideparkmgr.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.beonelot.com
 *
 * @version: V1.0
 * @Copyright: www.beonelot.com Inc. All rights reserved.
 * @Description：
 * @Date: 2021-11-05
 * @Author: Lingnan
 **/
@APCOSApi(value = "路边停车手机端接口", developers = {"lingnan"}, description = "路边停车手机端接口")
@RestController
@RequestMapping("/cdsideparkmgr/cdsideparkmgrForApp")
@Slf4j
public class AppController {
    @Autowired
    private ICdsideparkmgrParkRecordService parkRecordService;
    @Autowired
    private ICdsideparkmgrOrderInfoService cdsideparkmgrOrderInfoService;
    @Autowired
    private CdsideparkmgrRpc cdsideparkmgrRpc;
    @Autowired
    private ICdsideparkmgrEmployeeService cdsideparkmgrEmployeeService;
    @Autowired
    private ICdsideparkmgrProjectService iCdsideparkmgrProjectService;
    @Autowired
    private CdsideparmgrkUserMapper cdsideparmgrkUserMapper;
    @Autowired
    private CdsideparkmgrNoticeMapper cdsideparkmgrNoticeMapper;
    @Autowired
    private CdsideparkmgrProjectCarMapper cdsideparkmgrProjectCarMapper;
    @Autowired
    private ICdsideparkmageCarInsideService carInsideService;
    @Autowired
    private ICdsideparkmgrCarInfoService carInfoService;
    @Autowired
    private ICdsideparkmageOwnVehicleService ownVehicleService;
    private DateTimeFormatter df =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @APCOSApiOperation(value = "获取我管理的项目", developers = {"lingnan"}, description = "获取我管理的项目",
            infType = APCOSApiConstans.INF_TYPE_OTHER, infCategory = APCOSApiConstans.INF_CATEGORY_ALL)
    @GetMapping("getMyManagedProject")
    public JsonResult getMyManagedProject(@RequestParam(name = "projectType",required = false)Integer projectType){
        SysUserVO currentUser = cdsideparkmgrRpc.getCurrentUser();
        if(currentUser == null){
            return JsonResult.error("获取登录信息失败");
        }
        HashMap param = new HashMap();
        param.put("userId",currentUser.getUserId());
        List<CdyardmgrEmplayee> emplayeeList = cdsideparkmgrEmployeeService.list(param);
        if(emplayeeList.size() == 0){
            return JsonResult.error("该账号没有管理的项目");
        }
        Set<String> projectIdSet = emplayeeList.stream().map(CdyardmgrEmplayee::getYardId).collect(Collectors.toSet());
        HashMap param2 = new HashMap();
        param2.put("projectIdSet",projectIdSet);
        CdparkmanagerProject project = iCdsideparkmgrProjectService.selectOne(param2);
        return project != null ? JsonResult.ok(project) : JsonResult.error("没有管理的项目");
    }

    @APCOSApiOperation(value = "获取我的管理信息", developers = {"lingnan"}, description = "获取我的管理信息",
            infType = APCOSApiConstans.INF_TYPE_OTHER, infCategory = APCOSApiConstans.INF_CATEGORY_ALL)
    @GetMapping("getMyManagedInfo")
    public JsonResult getMyManagedInfo(){
        SysUserVO currentUser = cdsideparkmgrRpc.getCurrentUser();
        if(currentUser == null){
            return JsonResult.error("获取登录信息失败");
        }
        HashMap param = new HashMap();
        param.put("userId",currentUser.getUserId());
        List<CdyardmgrEmplayee> emplayeeList = cdsideparkmgrEmployeeService.list(param);
        if(emplayeeList.size() == 0){
            return JsonResult.error("该账号没有管理的车场");
        }
        List<String> projectNames = new ArrayList<>();
        HashMap<String,List<CdparkmanagerProjectCar>> cwMap = new HashMap<>();
        HashMap<String,List<String>> qyMap = new HashMap<>();
        for(CdyardmgrEmplayee emplayee : emplayeeList){
            HashMap param2 = new HashMap();
            String projectId = emplayee.getYardId();
            param2.put("id", projectId);
            param2.put("projectStatus",Constant.PROJECT_STATUS_ENABLED);
            param2.put("projectType",Constant.PROJECT_TYPE_SIDE_PARK);
            CdparkmanagerProject project = iCdsideparkmgrProjectService.selectOne(param2);
            if(project != null){
                projectNames.add(project.getProjectName());
                HashMap param3 = new HashMap();
                param3.put("projectId",projectId);
                List<CdparkmanagerProjectCar> list = cdsideparkmgrProjectCarMapper.list(param3);
                if (list.size() > 0){
                    cwMap.put(project.getProjectName(),list);
                }
                List<String> qyList = cdsideparkmgrProjectCarMapper.listLocations(projectId);
                if(qyList.size() > 0){
                    qyMap.put(project.getProjectName(),qyList);
                }
            }
        }
        List<Object> dataList = new ArrayList<>();
        dataList.add(cwMap);
        dataList.add(qyMap);
        return JsonResult.ok(dataList);
    }

    @APCOSApiOperation(value = "获取未支付的记录", developers = {"lingnan"}, description = "获取未支付的记录",
            infType = APCOSApiConstans.INF_TYPE_OTHER, infCategory = APCOSApiConstans.INF_CATEGORY_ALL)
    @GetMapping("listUnPayedRecord")
    public JsonResult listUnPayedRecord(@RequestParam(required = false) String area,
                                        @RequestParam(required = false) String stall,
                                        @RequestParam(required = false) String parkTime){
        HashMap param = new HashMap();
        param.put("area",area);
        param.put("stall",stall);
        param.put("parkTime",parkTime);
        List<CdsideparkmgrParkRecord> list = parkRecordService.list(param);
        return JsonResult.ok(list);
    }

    @APCOSApiOperation(value = "确认驶离", developers = {"lingnan"}, description = "确认驶离",
            infType = APCOSApiConstans.INF_TYPE_OTHER, infCategory = APCOSApiConstans.INF_CATEGORY_ALL)
    @PostMapping("/confirmLeave")
    @Transactional(rollbackFor = Exception.class)
    public JsonResult confirmLeave(String id,String orderId){
        if(StringUtils.isEmpty(id)){
            return JsonResult.error("记录id不存在");
        }
        if(StringUtils.isEmpty(orderId)){
            return JsonResult.error("订单id不存在");
        }
        CdsideparkmgrParkRecord parkRecord = parkRecordService.selectByKey(id);
        if(parkRecord == null){
            return JsonResult.error("记录不存在");
        }
        CdsideparkmgrParkRecord parkRecordNew = new CdsideparkmgrParkRecord();
        parkRecordNew.setId(id);
        parkRecordNew.setLeaveTime(LocalDateTime.now());
        JsonResult jsonResult = parkRecordService.saveOrUpdate(parkRecordNew);
        if (jsonResult.getSuccess()){
            //移除场内车辆
            String carNo = parkRecord.getCarNo();
            removeCarInside(carNo,parkRecord.getProjectId());
            CdfinanmodOrder order = new CdfinanmodOrder();
            order.setId(orderId);
            order.setOutTime(LocalDateTime.now());
            // 计算金额
            JsonResult result = cdsideparkmgrOrderInfoService.update(order);
            if(result.getSuccess()){
                // 发送出场通知
                JSONObject msgJson = new JSONObject();
                JSONObject titleJson = new JSONObject();
                titleJson.put("value","您的爱车已驶离停车场");
                titleJson.put("color","#173177");
                msgJson.put("first",titleJson);
                JSONObject locationJson = new JSONObject();
                locationJson.put("value", parkRecord.getArea());//停车场
                locationJson.put("color","#173177");
                msgJson.put("keyword1",locationJson);
                JSONObject carNumJson = new JSONObject();
                carNumJson.put("value", carNo);//车牌号
                carNumJson.put("color","#173177");
                msgJson.put("keyword2",carNumJson);
                JSONObject remarkJson = new JSONObject();
                remarkJson.put("value","欢迎下次光临！");
                remarkJson.put("color","#173177");
                msgJson.put("remark",remarkJson);
                List<String> openIds = getOpenIds(carNo);
                if(openIds.size() > 0){
                    String templateId = getTemplateId(Constant.TITLE_TYPE_EXIT);
                    for (String openId : openIds) {
                        cdsideparkmgrRpc.pushPaMsg(templateId,openId,msgJson.toJSONString());
                    }
                }
            }
            return JsonResult.ok("确认离场成功");
        }
        return JsonResult.error("确认离场失败");
    }

    private void removeCarInside(String carNumber, String projectId) {
        HashMap param = new HashMap();
        param.put("carNumber",carNumber);
        param.put("projectId",projectId);
        param.put("isDel",Constant.IS_DEL_NO);//未删除
        CdyardmgrCarInside carInside = carInsideService.selectOne(param);
        if(carInside == null){return;}
        CdyardmgrCarInside carInsideNew = new CdyardmgrCarInside();
        long min = DateUtil.getDifferMin(carInsideNew.getEnterTime(), LocalDateTime.now());
        carInsideNew.setId(carInside.getId());
        carInsideNew.setStayTime(min);
        carInsideNew.setIsDel(Constant.IS_DEL_YES);
        carInsideNew.setRemark("正常出入场");
        carInsideService.updateByKey(carInsideNew);
    }

    // 路边停靠入场登记
    @APCOSApiOperation(value = "路边停靠入场登记", developers = {"lingnan"}, description = "路边停靠入场登记",
            infType = APCOSApiConstans.INF_TYPE_OTHER, infCategory = APCOSApiConstans.INF_CATEGORY_ALL)
    @PostMapping("/rcRegist")
    @Transactional(rollbackFor = Exception.class)
    public JsonResult wpcjcRegist(@RequestBody CdsideparkmgrParkRecord registInfo){
        SysUserVO currentUser = cdsideparkmgrRpc.getCurrentUser();
        SysOrgInfo currentOrg = cdsideparkmgrRpc.getCurrentOrg();
        if(currentUser == null || currentOrg == null){
            return JsonResult.error("获取登录信息失败");
        }
        if(registInfo == null){
            return JsonResult.error("参数错误");
        }
        String carNo = registInfo.getCarNo();
        if(StringUtils.isEmpty(carNo)){
            return JsonResult.error("车牌号不存在");
        }
        String orderId = StringUtil.getUuid();
        registInfo.setOrderId(orderId);
        registInfo.setUserId(currentUser.getUserId());
        registInfo.setUserName(currentUser.getUserAccount());
        registInfo.setCategoryId(Constant.STRING_NUMER_ONE);
        registInfo.setCategory(Constant.CAR_TYPE_TEMP);
        JsonResult jsonResult = parkRecordService.saveOrUpdate(registInfo);
        if(jsonResult.getSuccess()){
            String recordId = (String) jsonResult.getData();
            // 新增场内车辆数据
            HashMap param2 = new HashMap();
            param2.put("province",carNo.substring(0,1));
            param2.put("carNo2",carNo.substring(1).trim());
            String projectId = registInfo.getProjectId();
            param2.put("yardId", projectId);
            param2.put("flag","common");
            CdyardmgrCarInside carInside = new CdyardmgrCarInside();
            CdyardmgrCarInfo cdyardmgrCarInfo = carInfoService.selectOne(param2);
            if(cdyardmgrCarInfo != null){
                carInside.setCategory(cdyardmgrCarInfo.getCategory());
            }else {
                carInside.setCategory("临停车");
            }
            carInside.setCarNo(carNo);
            HashMap param3 = new HashMap();
            param3.put("ownVehicle",carNo);
            param3.put("isAuth",Constant.IS_AUTHED);
            CdhymgtOwnVehicles ownVehicles = ownVehicleService.selectOne(param3);
            if(ownVehicles != null){
                carInside.setPhone(ownVehicles.getMemberAccount());
            }else {
                carInside.setPhone("-");
            }
            carInside.setProjectId(projectId);
            carInside.setIsDel(Constant.IS_DEL_NO);
            carInside.setId(recordId);
            carInsideService.saveOrUpdate(carInside,true);
            CdfinanmodOrder order = new CdfinanmodOrder();
            order.setId(orderId);
            order.setBusinessId(currentOrg.getOrgId());
            order.setProId(projectId);
            order.setParkSite(registInfo.getArea());
            order.setCreatedBy(currentUser.getUserAccount());
            order.setOrderFrom(Constant.ORDER_FROM_SIDERORAD); // 订单来源 3.路边停车
            order.setCarNum(carNo);// 无牌车手机号作为车牌号信息
            order.setOrderId(System.currentTimeMillis()+"");
            order.setParkRecordId(recordId);
            LocalDateTime now = LocalDateTime.now();
            order.setCreatedTime(now);
            order.setEnterTime(now);
            // 交易状态1.未缴费2.已缴费3.退款
            order.setDealStatus(Constant.DEAL_STATUS_UNPAYED);
            // 是否删除  1.删除 2.不删除
            order.setIsDel(Constant.ORDER_UNDELETED);
            JsonResult jsonResult2 = cdsideparkmgrOrderInfoService.save(order);
            if(jsonResult2.getSuccess()){
                // 发送进场通知
                JSONObject msgJson = new JSONObject();
                JSONObject titleJson = new JSONObject();
                titleJson.put("value","尊敬的车主，您好，您的车辆已入场");
                titleJson.put("color","#173177");
                msgJson.put("first",titleJson);
                JSONObject carNumJson = new JSONObject();
                carNumJson.put("value",carNo);//车牌号
                carNumJson.put("color","#173177");
                msgJson.put("keyword1",carNumJson);
                JSONObject locationJson = new JSONObject();
                locationJson.put("value", registInfo.getArea());//停车场
                locationJson.put("color","#173177");
                msgJson.put("keyword2",locationJson);
                JSONObject timeJson = new JSONObject();
                timeJson.put("value", df.format(LocalDateTime.now()));// 入场时间
                timeJson.put("color","#173177");
                msgJson.put("keyword3",timeJson);
                JSONObject remarkJson = new JSONObject();
                remarkJson.put("value","欢迎光临！祝您生活愉快！");
                remarkJson.put("color","#173177");
                msgJson.put("remark",remarkJson);
                List<String> openIds = getOpenIds(carNo);
                if(openIds.size() > 0){
                    String templateId = getTemplateId(Constant.TITLE_TYPE_ENTRANCE);
                    for (String openId : openIds) {
                        cdsideparkmgrRpc.pushPaMsg(templateId,openId,msgJson.toJSONString());
                    }
                }
                return JsonResult.ok("路边停车登记成功");
            }
            return JsonResult.error("路边停车登记失败");
        }
        return JsonResult.error("路边停车登记失败");
    }

    private List<String> getOpenIds(String carNo){
        HashMap param = new HashMap();
        param.put("carNo",carNo);
        param.put("isDel",Constant.ORDER_UNDELETED);
        List<CdfinanmodUser> list = cdsideparmgrkUserMapper.list(param);
        List<String> openIdList = new ArrayList<>();
        list.forEach(item->{
            String mpOpenid = item.getMpOpenid();
            if (!StringUtil.isEmpty(mpOpenid)){
                openIdList.add(mpOpenid);
            }
        });
        return openIdList;
    }

    private String getTemplateId(String titleType){
        HashMap param = new HashMap();
        CdgzhpzNotice notice = cdsideparkmgrNoticeMapper.selectOne(param);
        if(null == notice){return "";}
        switch (titleType){
            case Constant.TITLE_TYPE_ENTRANCE:return notice.getEnterTemplate();
            case Constant.TITLE_TYPE_PAY:return notice.getPayTemplate();
            case Constant.TITLE_TYPE_EXIT:return notice.getOutTemplate();
            default:return "";
        }
    }
}
